#pragma once
#include <iostream>
#include <fstream>
#include <time.h>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdarg.h>
// 日志代码
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
const static char *logname = "log.txt";
bool g_save = false;
// 日志等级---> 获取
enum level
{
    DEBUG = 0,
    INFO = 1,
    WARNING = 2,
    ERROR = 3,
    FATAL = 4
};
// 获取日志等级
std::string Get_Level(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
    case INFO:
        return "INFO";
    case WARNING:
        return "WARING";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return "None";
    }
}
// 获取时间
std::string Get_Time()
{
    time_t timestamp = time(nullptr);
    struct tm *formate_time = localtime(&timestamp);
    char buffer[1024];
    snprintf(buffer, sizeof(buffer), "%d-%d-%d %d:%d:%d",
             formate_time->tm_year + 1980,
             formate_time->tm_mon + 1,
             formate_time->tm_wday,
             formate_time->tm_hour,
             formate_time->tm_min,
             formate_time->tm_sec);
    return buffer;
}
// 保存文件
void save_file(const std::string &filename, const std::string &message)
{
    std::ofstream outfile(filename, std::ios::app);
    if (!outfile.is_open())
    {
        std::cout << "file open failed!" << std::endl;
        exit(-1);
    }
    outfile << message << std::endl;
    return;
}
// 整合日志信息
void log_inf(std::string filename, int line, int level, bool is_save, const char *formate, ...)
{
    std::string level_str = Get_Level(level);
    std::string time_str = Get_Time();
    pid_t id = getpid();
    va_list arg;
    va_start(arg, formate);
    char buffer[2014];
    vsnprintf(buffer, sizeof(buffer), formate, arg);
    va_end(arg);
    std::string message = "[" + time_str + "]" + "[" + level_str + "]" + "[" + std::to_string(id) + "]" + "[" + filename + "]" + "[" + std::to_string(line) + "]" + buffer;
    pthread_mutex_lock(&mutex);
    if (is_save)
    {
        save_file(logname, message);
    }
    else
    {
        std::cout << message;
    }
    pthread_mutex_unlock(&mutex);
}
// 定义宏
#define LOG(level, formate, ...)                                            \
    do                                                                      \
    {                                                                       \
        log_inf(__FILE__, __LINE__, level, g_save, formate, ##__VA_ARGS__); \
    } while (0)
    
#define Enablefile()   \
    do {               \
        g_save = true; \
    } while (0)

#define EnableScrean()  \
    do {               \
        g_save = false; \
    } while (0)
